package com.useeinfo.oa.modules.maintaining.biz;

import com.useeinfo.framework.extend.biz.CrudBiz;
import com.useeinfo.framework.sugar.data.QueryParam;
import com.useeinfo.framework.sugar.func.file.FileUtils;
import com.useeinfo.framework.sugar.tools.Configuration;
import com.useeinfo.framework.sugar.tools.DateTimeUtils;
import com.useeinfo.framework.sugar.tools.StringConverters;
import com.useeinfo.oa.common.config.ConstantKeyFilePath;
import com.useeinfo.oa.common.utils.ResultUtil.ResultDto;
import com.useeinfo.oa.common.utils.ResultUtil.ResultUtil;
import com.useeinfo.oa.modules.base.biz.AuditFlowBiz;
import com.useeinfo.oa.modules.base.biz.FacilityBiz;
import com.useeinfo.oa.modules.base.biz.PositionBiz;
import com.useeinfo.oa.modules.base.biz.ResourceBiz;
import com.useeinfo.oa.modules.base.entity.*;
import com.useeinfo.oa.modules.base.enums.ResourceTypeEnum;
import com.useeinfo.oa.modules.maintaining.dao.PlannerOrderDao;
import com.useeinfo.oa.modules.maintaining.entity.FacilityMaintain;
import com.useeinfo.oa.modules.maintaining.entity.PeriodInstall;
import com.useeinfo.oa.modules.maintaining.entity.PlannerOrder;
import com.useeinfo.oa.modules.maintaining.enums.OrderAssignTypeEnum;
import com.useeinfo.oa.modules.maintaining.enums.OrderOperationEnum;
import com.useeinfo.oa.modules.maintaining.enums.PlannerStatusEnum;
import com.useeinfo.oa.modules.security.biz.OrganizationBiz;
import com.useeinfo.oa.modules.security.biz.SystemUserBiz;
import com.useeinfo.oa.modules.security.entity.SystemUser;
import com.useeinfo.oa.modules.security.util.SessionKeyUtils;
import com.useeinfo.oa.modules.threadUtil.ThreadUtils;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.hibernate.loader.custom.Return;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import java.util.*;

@Service("plannerOrderBiz")
public class PlannerOrderBiz extends CrudBiz<PlannerOrderDao, PlannerOrder> {
    @Autowired
    private ResourceBiz resourceBiz;
    @Autowired
    private AuditFlowBiz auditFlowBiz;

    @Autowired
    private SystemUserBiz systemUserBiz;
    @Autowired
    private OrganizationBiz organizationBiz;
    @Autowired
    private PeriodInstallBiz periodInstallBiz;
    @Autowired
    private FacilityMaintainBiz facilityMaintainBiz;
    @Autowired
    private PositionBiz positionBiz;
    @Autowired
    private PlannerOrderLogBiz plannerOrderLogBiz;
    @Autowired
    private MaintainOrderBiz maintainOrderBiz;
    @Autowired
    private FacilityBiz facilityBiz;
    @Autowired
    private PlanExecuteTimeBiz planExecuteTimeBiz;


    /**
     * 开始计划，停止计划
     *
     * @param ids
     * @param request
     * @param type
     * @param plannerStatusEnum
     * @return
     */
    public ResultDto planner(String ids, HttpServletRequest request, int type, PlannerStatusEnum plannerStatusEnum) {
        Enterprise enterprise = SessionKeyUtils.getSessionEnterprise(request);
        SystemUser systemUser = SessionKeyUtils.getSessionUser(request);
        if (enterprise == null || systemUser == null) {
            return ResultUtil.error("session过期，请重新登陆");
        }
        net.sf.json.JSONArray jsonArray = net.sf.json.JSONArray.fromObject(ids);
        for (Object id : jsonArray) {
            PlannerOrder plannerOrder = dao.findModel(StringConverters.null2Long(id));
            if (type == 0 && plannerOrder.getPlannerStatusEnum().getCode().equals("START")) {
                return ResultUtil.error("不能开始已经开始的计划");
            }
            if (type == 1 && plannerOrder.getPlannerStatusEnum().getCode().equals("STOP")) {
                return ResultUtil.error("不能停止已经停止的计划");
            }
        }
        for (Object id : jsonArray) {
            PlannerOrder plannerOrder = dao.findModel(StringConverters.null2Long(id));
            plannerOrder.setPlannerStatusEnum(plannerStatusEnum);
            dao.update(plannerOrder);
            if(type==1){
                planExecuteTimeBiz.setOperateStatus(0,StringConverters.null2Long(id));
            }else if(type==0){
                planExecuteTimeBiz.setOperateStatus(1,StringConverters.null2Long(id));
            }
            //操作日志
            plannerOrderLogBiz.savePlannerLog(plannerOrder, type == 0 ? OrderOperationEnum.START : OrderOperationEnum.END, request);
        }
        return ResultUtil.success();

    }

    /**
     * 保存计划工单
     *
     * @param plannerOrder
     * @param pic1
     * @param sImg1
     * @param start
     * @param end
     * @param selectCompleteAuditFlowIds
     * @param selectDelayAuditFlowIds
     * @param selectOrganizationIds
     * @param selectPeriodInstallIds
     * @param request
     * @param facilityMaintainIds
     * @return
     */
    public ResultDto save(PlannerOrder plannerOrder, MultipartFile pic1, String sImg1, String start, String end, List<String> selectCompleteAuditFlowIds,
                          List<String> selectDelayAuditFlowIds,List<String> selectCancelAuditFlowIds, List<String> selectOrganizationIds, List<String> selectPeriodInstallIds,
                          HttpServletRequest request, String facilityMaintainIds,String resourceId) {
        Enterprise enterprise = SessionKeyUtils.getSessionEnterprise(request);
        SystemUser systemUser = SessionKeyUtils.getSessionUser(request);
        QueryParam queryParam=new QueryParam();
        queryParam.getSqlMap().put("orderName",plannerOrder.getName());
        queryParam.getSqlMap().put("enterprise",enterprise.getId()+"");
        List<PlannerOrder>plannerOrders=dao.findList(queryParam);
        if((CollectionUtils.isNotEmpty(plannerOrders)&& plannerOrder.getId()==null)||(plannerOrder.getId()!=null&&CollectionUtils.isNotEmpty(plannerOrders)&&plannerOrders.size()==1&&!plannerOrders.get(0).getId().equals(plannerOrder.getId()))){
            return ResultUtil.error("工单名称不能重复");
        }
        plannerOrder.setEnterprise(enterprise);
        plannerOrder.setCreateUser(systemUser);
        int flag = plannerOrder.getId() == null ? 0 : 1;//新增还是编辑
        //上传资料操作
        if ("1".equals(sImg1)) {
            //首先删除之前的关联资料文件
            plannerOrder.setResource(null);
            //如果有新资料文件 再存新资料文件
            String savePath1 = FileUtils.fileUpload(pic1, ConstantKeyFilePath.MAINTAINING_SAFETY_PDF_DIR, ConstantKeyFilePath.MAINTAINING_SAFETY_PDF_FIX, Configuration.getConfigurationByName("fileSaveRootPath"));
            if (StringUtils.isNotEmpty(savePath1)) {
                Resource resource = new Resource();
                String resourceName = pic1.getOriginalFilename();
                resource.setPath(savePath1);
                resource.setResourceName(resourceName);
                resource.setResourceTypeEnum(ResourceTypeEnum.PDF);
                resourceBiz.addOrUpdate(resource);
                plannerOrder.setResource(resource);
            }
        } else {
            Resource pinfo = new Resource();
            if (resourceId != null && !"".equals(resourceId)) {
                pinfo = resourceBiz.findModel(Long.valueOf(resourceId));
                plannerOrder.setResource(pinfo);
            }
        }
        plannerOrder.setStartTime(StringConverters.ToDateOnly(start));
        plannerOrder.setEndTime(StringConverters.ToDateOnly(end));
        if (CollectionUtils.isNotEmpty(selectCompleteAuditFlowIds)) {
            AuditFlow completeFlow = auditFlowBiz.findModel(StringConverters.ToLong(selectCompleteAuditFlowIds.get(0)));
            plannerOrder.setCompleteFlow(completeFlow.getFlow());
            plannerOrder.setAuditComplete(completeFlow);
        } else {
            //默认审批流
            if (auditFlowBiz.getDefaultFlow("complete", enterprise,2) != null) {
                plannerOrder.setCompleteFlow(auditFlowBiz.getDefaultFlow("complete", enterprise,2).getFlow());
                plannerOrder.setAuditComplete(auditFlowBiz.getDefaultFlow("complete", enterprise,2));
            }
        }
        if (CollectionUtils.isNotEmpty(selectDelayAuditFlowIds)) {
            AuditFlow delayFlow = auditFlowBiz.findModel(StringConverters.ToLong(selectDelayAuditFlowIds.get(0)));
            plannerOrder.setDelayFlow(delayFlow.getFlow());
            plannerOrder.setAuditDelay(delayFlow);
        } else {
            //默认审批流
            if (auditFlowBiz.getDefaultFlow("delay", enterprise,2) != null) {
                plannerOrder.setDelayFlow(auditFlowBiz.getDefaultFlow("delay", enterprise,2).getFlow());
                plannerOrder.setAuditDelay(auditFlowBiz.getDefaultFlow("delay", enterprise,2));
            }
        }
        if (CollectionUtils.isNotEmpty(selectCancelAuditFlowIds)) {
            AuditFlow cancelFlow = auditFlowBiz.findModel(StringConverters.ToLong(selectCancelAuditFlowIds.get(0)));
            plannerOrder.setCancelFlow(cancelFlow.getFlow());
            plannerOrder.setAuditCancel(cancelFlow);
        } else {
            //默认审批流
            if (auditFlowBiz.getDefaultFlow("cancel", enterprise,2) != null) {
                plannerOrder.setCancelFlow(auditFlowBiz.getDefaultFlow("cancel", enterprise,2).getFlow());
                plannerOrder.setAuditCancel(auditFlowBiz.getDefaultFlow("cancel", enterprise,2));
            }
        }
        if (CollectionUtils.isNotEmpty(selectOrganizationIds)) {
            plannerOrder.setOrganization(organizationBiz.findModel(StringConverters.ToLong(selectOrganizationIds.get(0))));
        }
        if (CollectionUtils.isNotEmpty(selectPeriodInstallIds)) {
            plannerOrder.setPeriodInstall(periodInstallBiz.findModel(StringConverters.ToLong(selectPeriodInstallIds.get(0))));
        }
        if (plannerOrder.getId() == null) {
            dao.add(plannerOrder);
        } else {
            dao.update(plannerOrder);
        }
        plannerOrder.setFacilityMaintains(facilityMaintainBiz.findByIds(facilityMaintainIds, plannerOrder));
        //清空无效维保内容
        facilityMaintainBiz.deleteUselessData();
        //操作日志
        plannerOrderLogBiz.savePlannerLog(plannerOrder, flag == 0 ? OrderOperationEnum.CREATE_PLANNER : OrderOperationEnum.EDIT, request);
        //周期性计划生成事件列表保存到临时表中，方便调度生成工单
        ThreadUtils.periodExecuteOrder(periodInstallBiz, plannerOrder);
        return ResultUtil.success();
    }

    /**
     * 指派人员
     *
     * @param assignIds
     * @param plannerId
     * @return
     */
    public ResultDto assignUsers(String assignIds, String plannerId, HttpServletRequest request) {
        net.sf.json.JSONArray jsonArray = net.sf.json.JSONArray.fromObject(assignIds);
        PlannerOrder plannerOrder = dao.findModel(StringConverters.null2Long(plannerId));
        Set<SystemUser> systemUsers = plannerOrder.getAssignUsers();
        if (systemUsers == null) {
            systemUsers = new HashSet<>();
        }
        for (Object id : jsonArray) {
            SystemUser systemUser = systemUserBiz.findModel(StringConverters.null2Long(id));
            if (systemUser != null) {
                systemUsers.add(systemUser);
            }
        }
        plannerOrder.setAssign(Boolean.TRUE);
        plannerOrder.setOrderAssignTypeEnum(OrderAssignTypeEnum.USER);
        plannerOrder.setAssignUsers(systemUsers);
        dao.update(plannerOrder);
        //操作日志
        plannerOrderLogBiz.savePlannerLog(plannerOrder, OrderOperationEnum.ASSIGN_USER, request);
        return ResultUtil.success();
    }

    /**
     * 指派岗位
     *
     * @param assignIds
     * @param plannerId
     * @return
     */
    public ResultDto assignPositions(String assignIds, String plannerId, HttpServletRequest request) {
        net.sf.json.JSONArray jsonArray = net.sf.json.JSONArray.fromObject(assignIds);
        PlannerOrder plannerOrder = dao.findModel(StringConverters.null2Long(plannerId));
        Set<Position> positions = plannerOrder.getAssignPositions();
        if (positions == null) {
            positions = new HashSet<>();
        }
        for (Object id : jsonArray) {
            Position position = positionBiz.findModel(StringConverters.null2Long(id));
            if (positions != null) {
                positions.add(position);
            }
        }
        plannerOrder.setAssign(Boolean.TRUE);
        plannerOrder.setOrderAssignTypeEnum(OrderAssignTypeEnum.POSITION);
        plannerOrder.setAssignPositions(positions);
        dao.update(plannerOrder);
        //操作日志
        plannerOrderLogBiz.savePlannerLog(plannerOrder, OrderOperationEnum.ASSIGN_POSITION, request);
        return ResultUtil.success();
    }

    /**
     * 强制生成指定日实施单
     *
     * @param id
     * @param delay
     * @param delayDate
     * @return
     */
    public ResultDto saveAssignDate(String id, String delay, String delayDate, HttpServletRequest request) {
        PlannerOrder plannerOrder = dao.findModel(StringConverters.null2Long(id));
        if (StringConverters.null2Boolean(delay)) {
            plannerOrder.setDelay(StringConverters.null2Boolean(delay));
            plannerOrder.setDelayDate(StringConverters.ToDatePattern(delayDate, "yyyy-MM-dd HH:mm"));
            dao.update(plannerOrder);
            //周期性计划生成事件列表保存到临时表中，方便调度生成工单
            ThreadUtils.periodExecuteOrder(periodInstallBiz, plannerOrder);
            //操作日志
            plannerOrderLogBiz.savePlannerLog(plannerOrder, OrderOperationEnum.ASSIGN_DATE, request);
        } else {
            //TODO 在此调用生成一次性工单的方法，开始时间，delayDate,结束时间，plannerOrder.getEndTime()+23:59:59
            maintainOrderBiz.makeMaintainOrder(plannerOrder,StringConverters.formatDate(delayDate,"yyyy-MM-dd HH:mm"),DateTimeUtils.getEndOfDay1(plannerOrder.getEndTime()),0,null);
        }
        return ResultUtil.success();
    }


    /**
     * app接口保存周期计划
     * @param request
     * @return
     */
    @Transactional(readOnly = false)
    public ResultDto savePlanner(String name,String degree,String startTime,String endTime,String required,String remindTime,String periodId,
                                 String  assignUser,String assignPosition,String completeAuditId,String delayAuditId,String cancelAuditId,
                                String maintainData, HttpServletRequest request){
        Enterprise enterprise=SessionKeyUtils.getSessionEnterprise(request);
        SystemUser systemUser=SessionKeyUtils.getSessionUser(request);
        if(enterprise==null || systemUser==null){
            return ResultUtil.error("登陆过期，请重新登陆");
        }

        PlannerOrder plannerOrder=new PlannerOrder();
        plannerOrder.setEnterprise(enterprise);
        plannerOrder.setCreateUser(systemUser);
        plannerOrder.setSerial(StringConverters.getRandomString(10));
        plannerOrder.setName(name);
        plannerOrder.setDegree(degree);
        plannerOrder.setStartTime(StringConverters.formatDate(startTime,"yyyy-MM-dd"));
        plannerOrder.setEndTime(StringConverters.formatDate(endTime,"yyyy-MM-dd"));
        plannerOrder.setRequired(required);
        plannerOrder.setRemindTime(StringConverters.null2Int(remindTime));
        //所属周期
        PeriodInstall periodInstall=periodInstallBiz.findModel(StringConverters.null2Long(periodId));
        if(periodInstall==null){
            return ResultUtil.error("周期选择有误，请重新选择");
        }
        plannerOrder.setPeriodInstall(periodInstall);
        //指派数据
        JSONArray userArray=JSONArray.fromObject(assignUser);
        JSONArray positionArray=JSONArray.fromObject(assignPosition);
        if(userArray.size()!=0&& positionArray.size()!=0){
            return ResultUtil.error("指派只能选择一种类型");
        }else if(userArray.size()!=0){//指派人员
            plannerOrder.setOrderAssignTypeEnum(OrderAssignTypeEnum.USER);
            Set<SystemUser>systemUserSet=new HashSet<>();
            userArray.forEach(x->{
                systemUserSet.add(systemUserBiz.findModel(StringConverters.null2Long(x)));
            });
            plannerOrder.setAssignUsers(systemUserSet);
            plannerOrder.setAssign(true);
        }else if(positionArray.size()!=0){//指派岗位
            plannerOrder.setOrderAssignTypeEnum(OrderAssignTypeEnum.POSITION);
            Set<Position>positionHashSet=new HashSet<>();
            positionArray.forEach(x->{
                positionHashSet.add(positionBiz.findModel(StringConverters.null2Long(x)));
            });
            plannerOrder.setAssign(true);
            plannerOrder.setAssignPositions(positionHashSet);
        }
        AuditFlow completeFlow=auditFlowBiz.findModel(StringConverters.null2Long(completeAuditId));//完成审批流
        if(completeFlow==null){
            completeFlow=auditFlowBiz.getDefaultFlow("complete",enterprise,2);
        }
        plannerOrder.setCompleteFlow(completeFlow!=null?completeFlow.getFlow():"");
        plannerOrder.setAuditComplete(completeFlow);

        AuditFlow delayFlow=auditFlowBiz.findModel(StringConverters.null2Long(delayAuditId));//延期审批流
        if(delayFlow==null){
            delayFlow=auditFlowBiz.getDefaultFlow("delay",enterprise,2);
        }
        plannerOrder.setDelayFlow(delayFlow!=null?delayFlow.getFlow():"");
        plannerOrder.setAuditDelay(delayFlow);

        AuditFlow cancelFlow=auditFlowBiz.findModel(StringConverters.null2Long(cancelAuditId));//取消审批流
        if(cancelFlow==null){
            cancelFlow=auditFlowBiz.getDefaultFlow("cancel",enterprise,2);
        }
        plannerOrder.setCancelFlow(cancelFlow!=null?cancelFlow.getFlow():"");
        plannerOrder.setAuditCancel(cancelFlow);
        dao.add(plannerOrder);
        //设备工艺数据
        JSONArray maintainArray=JSONArray.fromObject(maintainData);
        if(maintainArray.size()==0){
            return ResultUtil.success("请添加设备");
        }
        Set<FacilityMaintain>facilityMaintainSet=new HashSet<>();
        maintainArray.forEach(x->{
            String facilityId=JSONObject.fromObject(x).getString("facilityId");
            String maintainId=JSONObject.fromObject(x).getString("maintainId");
            FacilityMaintain facilityMaintain= facilityMaintainBiz.saveFacilityMaintain(plannerOrder.getId()+"",facilityId,maintainId, enterprise);
//            if(facilityMaintain==null){
//                return ResultUtil.error("添加的设备或工作要求有误");
//            }
            facilityMaintainSet.add(facilityMaintain);
            plannerOrder.setFacilityMaintains(facilityMaintainSet);
            dao.update(plannerOrder);
        });
        plannerOrderLogBiz.savePlannerLog(plannerOrder,  OrderOperationEnum.CREATE_PLANNER, request);//log日志
        //周期性计划生成事件列表保存到临时表中，方便调度生成工单
        ThreadUtils.periodExecuteOrder(periodInstallBiz, plannerOrder);
        return ResultUtil.success();
    }

    //导出年度计划的设备基础数据
    public  List<Map<String, Object>> getYearPlan(String organizationId,String enterpriseId) {
        List<Map<String, Object>> mapList = new ArrayList<>();
        QueryParam queryParam=new QueryParam();
        queryParam.getSqlMap().put("organizationId",organizationId);
        queryParam.getSqlMap().put("enterpriseId",enterpriseId);

        List<Facility>facilityList=facilityBiz.findList(queryParam);
        facilityList.forEach(facility ->{
            Map<String, Object> testMap = new HashMap<>();
            testMap.put("name",facility.getName());
            testMap.put("code",facility.getCode());
            testMap.put("type",facility.getType()!=null?facility.getType():"");
            testMap.put("facilityId",facility.getId());
            mapList.add(testMap);
        } );
        return mapList;
    }
}
